package com.icebergteam.warfacewidget.core.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Log;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.icebergteam.warfacewidget.AppManager;
import com.icebergteam.warfacewidget.core.LogManager;
import com.icebergteam.warfacewidget.data.sql.CacheTable;
import com.icebergteam.warfacewidget.news.data.NewsParser;

public class ViewUtils {
	
	public static String className = ViewUtils.class.getCanonicalName();
	public static String ASSETURL = "file:///android_asset/";
	
	static public final int TYPE_MEDIA = 1;
	static public final int TYPE_VIDEO = TYPE_MEDIA << 1;
	
	public static String getErrorMessage( Exception e){
		StringWriter sw = new StringWriter();
		e.printStackTrace(new PrintWriter(sw));
		return sw.toString();
	}
	
	public static Drawable scaleImage(Drawable image, int boundBoxInDp) {

		// Get the ImageView and its bitmap
		Bitmap bitmap = ((BitmapDrawable) image).getBitmap();

		// Get current dimensions
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		// Determine how much to scale: the dimension requiring less scaling is
		// closer to the its side. This way the image always stays inside your
		// bounding box AND either x/y axis touches it.
		float xScale = ((float) boundBoxInDp) / width;
		float yScale = ((float) boundBoxInDp) / height;
		float scale = (xScale <= yScale) ? xScale : yScale;

		// Create a matrix for the scaling and add the scaling data
		Matrix matrix = new Matrix();
		matrix.postScale(scale, scale);

		// Create a new bitmap and convert it to a format understood by the
		// ImageView
		Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height,
				matrix, true);
		BitmapDrawable result = new BitmapDrawable(scaledBitmap);
		return result;//BitmapDrawable(AppManager.getContext().getResources(), scaledBitmap);
	}

	public static void scaleImage(ImageView view, int boundBoxInDp) {
		// Get the ImageView and its bitmap
		Drawable drawing = view.getDrawable();

		BitmapDrawable result = (BitmapDrawable) scaleImage(drawing,
				boundBoxInDp);
		int width = result.getBitmap().getWidth();
		int height = result.getBitmap().getHeight();
		view.setImageBitmap(result.getBitmap());

		// Now change ImageView's dimensions to match the scaled image
		LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view
				.getLayoutParams();
		params.width = width;
		params.height = height;
		view.setLayoutParams(params);
	}
	
	public static Bitmap scaleImage(String src, int boundBoxInDp) throws Exception{
		// Get the ImageView and its bitmap
		Drawable drawing = Drawable.createFromPath(src);

		BitmapDrawable result = (BitmapDrawable) scaleImage(drawing,
				boundBoxInDp);
	
		return result.getBitmap();
	}
	
	public static Bitmap scaleImage(Bitmap image, int boundBoxInDp) throws Exception{
		// Get the ImageView and its bitmap
		LogManager.LogEA(className, image);
		BitmapDrawable drawable = new BitmapDrawable(image);	

		BitmapDrawable result = (BitmapDrawable) scaleImage(drawable,
				boundBoxInDp);
	
		return result.getBitmap();
	}
	
	public static Bitmap scaleImage(int id, int boundBoxInDp) throws Exception{
		// Get the ImageView and its bitmap
		BitmapDrawable drawable = (BitmapDrawable)AppManager.getContext().getResources()
		        .getDrawable(id);
		

		BitmapDrawable result = (BitmapDrawable) scaleImage(drawable,
				boundBoxInDp);
	
		return result.getBitmap();
	}
	
	public static String getSourcePath(String url, String path, int type, boolean cache) throws Exception{
		String getPath = url;
		if(cache && !isLocalSrc(url)){
			if(type == ViewUtils.TYPE_MEDIA){
				String fileNameItem = String.format("%s%s%s", path, File.separatorChar, ViewUtils.getUrlPath(url));
				getPath =  ViewUtils.downloadFile(url, fileNameItem,false);
			}else if(type == ViewUtils.TYPE_VIDEO){
				String fileNameItem = String.format("%s%s%s.img", path, File.separator, UUID.randomUUID().toString());
				getPath = ViewUtils.downloadFile(url, fileNameItem,true);
			}
		}
		else{
			getPath = url;
		}
		return getPath;
	}
	
	public static boolean isLocalSrc(String url){
		return url.contains("file://");
	}
	
	public static String getSourcePath(String parent, String typeParent, String url, String path, int type, boolean cache) throws Exception{
		String getPath = url;
		
		if(cache){
			
			getPath = ViewUtils.getSourcePath(url, path, type, cache);
			
			ContentValues dataToInsert = new ContentValues();    
			dataToInsert.put(CacheTable.FIELD_PARENT, parent);
			dataToInsert.put(CacheTable.FIELD_FILE_URI, getPath);
			dataToInsert.put(CacheTable.FIELD_TYPE_PARENT, typeParent);
			AppManager.getDatabase().getCacheTable().updateOrInsert(dataToInsert);
		}
		else{
			getPath = url;
		}
		return getPath;
	}
	
	public static void downloadFile(final String parent, final String typeParent, final String url, final String path, final int type, final boolean download, final FileLoadingListener listener){
		(new AsyncTask<Void, Void, Void>() {
			@Override
			protected Void doInBackground(Void... params) {
				try {
					String link = null;
					LogManager.LogVA(className, parent, typeParent, url, path, type, download);
					try{
						Cursor cursor = AppManager.getDatabase().getCacheTable().getCacheByUrl(parent, path);
						cursor.moveToFirst();
						link = cursor.getString(cursor.getColumnIndex(CacheTable.FIELD_FILE_URI.trim()));
						
					}
					catch(Exception e){
						try{
							if(download){
								link = ViewUtils.getSourcePath(parent, typeParent, url, path, type, true);
							}
						}
						catch(Exception ex){
							LogManager.LogEA(className, "load rss logo", ex.getLocalizedMessage());
							listener.onLoadingFailed(url);
						}
					}
					
					listener.onLoadingComplete(link);
					
				} catch (Exception e) {
					LogManager.LogEA(className, e.getLocalizedMessage());
					listener.onLoadingFailed(url);
				}
				return null;
			}
		}).execute();
	}
	
	public static String convertFileToBase64(String fileName, AssetManager assetManager) {
		
		try {
			InputStream imageInFile = getInputStream(fileName, assetManager);
			String imageDataString = null;
			byte imageData[] = new byte[(int) imageInFile.available()];
			imageInFile.read(imageData);
			imageDataString = Base64.encodeToString(imageData, Base64.DEFAULT);
				
			imageInFile.close();
			//	LogManager.LogV(className, "ConvertFileToBase64", fileName, imageDataString);
			return imageDataString;
		} catch (Exception e) {
			LogManager.LogE(className,LogManager.getExecuteMethodName(), e.getMessage());
			e.printStackTrace();
			return null;
		}
	}
	
	public static Bitmap convertBase64ToFile(String str){
		byte[] imageAsBytes = Base64.decode(str.getBytes(),Base64.DEFAULT);
	    Bitmap image = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
	   LogManager.LogEA(className, str, imageAsBytes, imageAsBytes.length, image);
		return image;
	}
	
public static String convertFileToBase64(InputStream imageInFile) {
		
		try {
			String imageDataString = null;
			byte imageData[] = new byte[(int) imageInFile.available()];
			imageInFile.read(imageData);
			imageDataString = Base64.encodeToString(imageData, Base64.DEFAULT);
				
			imageInFile.close();
			//	LogManager.LogV(className, "ConvertFileToBase64", fileName, imageDataString);
			return imageDataString;
		} catch (Exception e) {
			LogManager.LogE(className,LogManager.getExecuteMethodName(), e.getMessage());
			e.printStackTrace();
			return null;
		}
	}

	public static InputStream getInputStream(String fileName,	AssetManager assetManager) throws Exception {
		InputStream imageInFile = null;
		
		if (fileName.contains(ASSETURL)) {
			if (assetManager == null) {
				LogManager.LogE(className, LogManager.getExecuteMethodName(), "AssetManager null object");
				
				return null;
			}
			String pathForAssetOpen = fileName.substring(fileName.length()
					- fileName.compareTo(ASSETURL));

			LogManager.LogV(className, LogManager.getExecuteMethodName(), pathForAssetOpen);
			
			imageInFile = assetManager.open(pathForAssetOpen);
			
			
		} else {
			String path = fileName.substring(fileName.indexOf("/"));

			
				imageInFile = new FileInputStream(path);
				LogManager.LogV(className, LogManager.getExecuteMethodName(), path);
			
			
		}
		return imageInFile;
	}
	
	public static void writeToFile(String fileName, String data){
		
	        try {
	            OutputStream outputStream = new FileOutputStream(new File(fileName));
	            outputStream.write(data.getBytes());
	            outputStream.flush();
	            outputStream.close();
	         }
	        catch (IOException e) {
	            LogManager.LogEA(fileName, "File write failed: " + e.toString());
	        }
	         
	    }
	 
	 public static String readFromFile(String fileName, AssetManager assetManager) {
	         
	        String ret = "";
	         
	        try {
	            InputStream inputStream = getInputStream(fileName, assetManager);
	             
	            if ( inputStream != null ) {
	                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
	                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
	                String receiveString = "";
	                StringBuilder stringBuilder = new StringBuilder();
	                 
	                while ( (receiveString = bufferedReader.readLine()) != null ) {
	                    stringBuilder.append(receiveString);
	                }
	                 
	                inputStream.close();
	                ret = stringBuilder.toString();
	            }
	        }
	        catch (FileNotFoundException e) {
	            LogManager.LogEA(className, "File not found: " + e.toString());
	        } catch (IOException e) {
	        	LogManager.LogEA(className, "Can not read file: " + e.toString());
	        } catch (Exception e) {
	        	 LogManager.LogEA(className, e.toString());
				e.printStackTrace();
			}
	 
	        return ret;
	    }
	
	 public static File createFile(String filename) {
	      File file = new File(filename);
	      File parent = file.getParentFile();
	      if (parent != null)
	          parent.mkdirs();
		  try {
				file.createNewFile();
		  } catch (IOException e) {
			  	if(!filename.equals(LogManager.LOG_FILE)){
			  		LogManager.LogEA(LogManager.className, e.getMessage());
			  	}
			  	else{
			  		Log.e(className, "not exists log file");
			  	}
		  }
	      return file;
	 }
	
	public static String downloadFile(String url, String fileName, boolean renameTomd5) throws MalformedURLException, IOException, NoSuchAlgorithmException{
		fileName = URLDecoder.decode(fileName, "UTF-8");
		
		File file = new File(fileName);
		
		if(!file.exists()){
			URLConnection conn = new URL(url).openConnection();
			conn.setConnectTimeout(NewsParser.TIMEOUT);
			conn.setReadTimeout(NewsParser.TIMEOUT);
			conn.connect();
			InputStream is = conn.getInputStream();
		
			file = createFile(fileName); 
			OutputStream out=new FileOutputStream(file);
		    byte buf[]=new byte[1024];
		    int len;
		    
		    MessageDigest md5 = null;
		    if(renameTomd5){
		    	 md5 = MessageDigest.getInstance("MD5");
		    }
				    
		    while((len= is.read(buf))>0){
		    		
		    	  out.write(buf,0,len);
		    	  if(renameTomd5){
		    		  md5.update(buf, 0, len);
		    	  }
		    	  
		    }
		  
		    out.close();
		    is.close();
		    
		    if(renameTomd5){
		    	String signature = new BigInteger(1,md5.digest()).toString(16);
		    	fileName = String.format("%s%s%s", getPath(fileName), File.separatorChar, signature);
		    	file.renameTo(new File(fileName));
		    }
		   
		}
		return fileName;
	}
	
	public static InputStream downloadFile(String url) throws MalformedURLException, IOException{
	
		
			URLConnection conn = new URL(url).openConnection();
			conn.setConnectTimeout(NewsParser.TIMEOUT);
			conn.setReadTimeout(NewsParser.TIMEOUT);
			conn.connect();
			InputStream is = conn.getInputStream();
		
			
		  
		   return is;	   
		   
		
	}
	
	public static String getUrlPath(String url) {
		try {
			return new URL(url).getPath();
		} catch (MalformedURLException e) {
			LogManager.LogE(className, LogManager.getExecuteMethodName(), e.getMessage(), url);
			e.printStackTrace();
			return url;
		}
	}
	
	public static String getPath(String url) {
	    int sep = url.lastIndexOf(File.separatorChar);
	    return url.substring(0, sep);
	}
		 
	public static String getExtFile(String name) {
		String ext;
	    if(name.lastIndexOf(".")==-1){
	      ext="";
	    
	    }else{
	      int index=name.lastIndexOf(".");
	      ext=name.substring(index+1,name.length());
	    }
	    return ext;
	}

	public static String getFileName(String fileName) {
		return fileName.substring( fileName.lastIndexOf(File.separatorChar)+1, fileName.length() );
	}

	public static String getMD5Str(InputStream is)
			throws NoSuchAlgorithmException, IOException {
		MessageDigest md5 = MessageDigest.getInstance("MD5");
		
		int read = is.read();
		
		   if (read != -1) {
			   md5.update((byte) read);
		   }
		   byte[] digest = md5.digest();
		   StringBuffer sb = new StringBuffer();
			for (byte b : digest) {
				sb.append(Integer.toHexString((int) (b & 0xff)));
			}
		return sb.toString();
	}
	public static boolean deleteFile(String fileName){
		boolean ok;
		Uri url;
		url =  Uri.parse(fileName);

		
File file = new File(url.getPath());
  if (file.isFile()){
		 
		  File parentFile =  file.getParentFile();
		  ok = file.delete();
		  if(parentFile != null && parentFile.listFiles().length == 0){
			  parentFile.delete();
		  }
		  
		  return ok;
  }
 return false;
	}
	
	public static void deleteRecursive(File fileOrDirectory) {
	    if (fileOrDirectory.isDirectory())
	        for (File child : fileOrDirectory.listFiles())
	            deleteRecursive(child);

	    fileOrDirectory.delete();
	}
	
	public static long getThreadId() {
		Thread t = Thread.currentThread();
		return t.getId();
	}

	public static String getThreadSignature() {
		Thread t = Thread.currentThread();
		long l = t.getId();
		String name = t.getName();
		long p = t.getPriority();
		String gname = t.getThreadGroup().getName();
		return (name + ":(id)" + l + ":(priority)" + p + ":(group)" + gname);
	}

	public static void logThreadSignature(String tag) {
		Log.d(tag, getThreadSignature());
	}

	public static void sleepForInSecs(int secs) {
		try {
			Thread.sleep(secs * 1000);
		} catch (InterruptedException x) {
			throw new RuntimeException(LogManager.getExecuteMethodName() + " interrupted", x);
		}
	}
	
	public static String findTextBeetweenTags(String startTag, String endTag, String source){
		int startPosition = source.indexOf(startTag) + startTag.length();  
		int endPosition = source.indexOf(endTag, startPosition);  
		return source.substring(startPosition, endPosition); 
	}
	
	public static String fixUrlString (String source) throws MalformedURLException{
		return new URL(source).toString();
	}
	
	public static void errorDialog(String title, String message, String positiveStr, OnClickListener positiveLis, String negativrStr, OnClickListener negativeLis, Context ctx){
		LogManager.LogV(className, LogManager.getExecuteMethodName(), message);

		new AlertDialog.Builder(ctx)
	      .setIcon(android.R.drawable.ic_dialog_alert)
	      .setTitle(title)
	      .setMessage(message)
	      .setPositiveButton(positiveStr, positiveLis)
	      .setNegativeButton(negativrStr, negativeLis)
	      .show();
	}

	
}